home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-05
/
pdclk139.zip
/
PING.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-05-17
|
16KB
|
748 lines
; ping.asm
;========================================================================
; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
MsgEchoHead db CR, LF, "Ping with packet size "
MsgEchoSweep db " "
MsgEchoSize db "0 and interval"
MsgEchoMs db " 0 ms to "
MsgEchoTarget db "1.2.3.4 :", CR, LF, LF
db "───────── Packets ──────── ║ ────── Delay ms ────── ║ Packet ║ Load ║ Time ", CR, LF
db "transmit receive diff ║ this min avg max ║ loss ║ kb/s ║ s ", CR, LF, "$$"
MsgEcho db " 0 0 0 0 0 0 0 0.0000 % 0 0 ", CR, '$'
MsgSerrTbl dw offset MsgSerrUnr
dw offset MsgSerrObuf
dw offset MsgSerrNoarp
dw offset MsgSerrTimout
dw offset MsgSerrNotraf
SERRTABLEN equ $-MsgSerrTbl
dw offset MsgSerrUnimpl
MsgSerrUnr db LF, "Host or net unreachable", CR, LF, '$'
MsgSerrObuf db LF, "Temporary out of buffers", CR, LF, '$'
MsgSerrNoarp db LF, "Got no ARP reply", CR, LF, '$'
MsgSerrTimout db LF, "Timeout", CR, LF, '$'
MsgSerrNotraf db LF, "Received no traffic from destination", CR, LF, '$'
MsgSerrUnimpl db LF, "Send Error.", CR, LF, '$'
even
EchoTarget dw 0, 0 ; echo argument values
EchoSize dw 30
EchoInterval dw 256
EchoData dw 101h
EchoDataIncW dw 1
EchoStart dw 0, 0, 0 ; echo variables
EchoNext dw 0
EchoLastDispl dw 0
EchoLastHi dw 0
EchoMaxSize dw 1500
EchoAvgSum dw 0, 0
EchoFudge dw 0
EchoLoad dw 0, 0
EchoDrop dw 0
PingRowCnt dw 17
EchoTx32 dw 0, 0 ; echo display variables
EchoRx32 dw 0, 0
EchoDif dw 0, 0
EchoThis dw 0
EchoMin dw 0ffffh
EchoAvg dw 0
EchoMax dw 0
EchoLoss dw 0, 0
EchoElapsed dw 0, 0
k27 dw 27
k55 dw 55
k100 dw 100
;************************************************************************
;* EchoAwhile
;************************************************************************
MsgCalling db "Calling nameserver(s)... $"
MsgNameRep db "got reply in "
MsgNameRepTim db " ms.", CR, LF, '$'
MsgBadName db LF, "Bad hostname.$"
EchoAwhile proc near
cmp EchoTarget,0 ; want to ping someone?
jne EchoYes
ret
EchoYes:
call InitTimer ; prepare millisecond timing
call HardwareTicks
mov EchoStart,si ; note start ticks
mov EchoStart+2,dx
mov EchoStart+4,ax
call DblShr10
mov EchoNext,ax
cmp EchoTarget,127 ; dns lookup to do?
jne EchoIpAddr
mov dx,offset MsgCalling
mov ah,9
int 21h
mov dx,2345h ; ping udp src port
xor ax,ax ; NsId
mov si,offset EchoNameBuf ; Ns question string
call NsResolve ; call nameserver(s)
call HardwareTicks ; response time
sub ax,EchoStart+4
sbb dx,EchoStart+2
div kTimerScale
mov di,offset MsgNameRepTim
mov PutNumFiller,' '
mov PutMinDigits,4
call PutNum
mov dx,offset MsgNameRep ; display it.
mov ah,9
int 21h
cmp EchoTarget,127 ; name resolved?
jne EchoIpAddr
mov dx,offset MsgBadName
mov ah,9
int 21h
EchoRet:
ret
EchoIpAddr:
test ArgFlags,MAKE_TABLE
jz EchoNotTbl
or GenFlags,TBL_READY
EchoNotTbl:
mov di,offset EchoSizeVec
mov cx,(EchoSizeEnd-EchoSizeVec)/2
xor ax,ax
rep stosw
test ArgFlags,TERM_WAIT
jnz EchoAsIs
cmp EchoInterval,128
jge EchoAsIs
mov EchoInterval,128
EchoAsIs:
call BufAlloc ; get a send buf
jz EchoRet
call MakeSendDescr
;*test mov [bx].dTickTimeout,8*18
mov [di].uIcmpTypeCode,8 ; type = echo request
mov cx,(1500-IPHDRLEN-ICMPHDRLEN)/2
add di,ICMPHDRLEN
mov ax,EchoData
EchoFillLoop:
stosw
add ax,EchoDataIncW
loop EchoFillLoop
EchoFillEnd:
mov si,offset EchoTarget-iIpSrc
call SwitchIpdstB ; set IP destination
mov si,offset EchoTarget
mov di,offset MsgEchoTarget
call PutIpNum ; tell who we are pinging
mov cx,EchoSize
or cx,cx
jns EchoSizePos
neg cx
mov MsgEchoSweep,'<'
EchoSizePos:
sub cx,IPHDRLEN+ICMPHDRLEN
cmp cx,GIANT-HWHDRLEN-IPHDRLEN-ICMPHDRLEN
jbe EchoOkSize
mov cx,30-IPHDRLEN-ICMPHDRLEN
EchoOkSize:
mov ax,cx
add ax,IPHDRLEN+ICMPHDRLEN
mov EchoSize,cx
mov EchoMaxSize,cx
mov di,offset MsgEchoSize
mov PutMinDigits,1
call PutNum ; and the packet size used
mov ax,EchoInterval
mov di,offset MsgEchoMs
mov PutMinDigits,6
mov PutNumFiller,' '
call PutNum ; and interval in ms
mov dx,offset MsgEchoHead
mov ah,9
int 21h ; display it
EchoLoop0:
nop ; (just to separate the loops)
EchoLoop:
call Something2Do ; process other things
jnz EchoLoop ; maybe more to do
call EchoDisplay ; show current values
call AnyKey ; first key stops sending
jz EchoNoKey
if 0
cmp al,'y' and 01fh ; ignore most control keys
jbe EchoNoKey
endif
jmp EchoEnd
EchoNoKey:
cmp FreeBufs.lBufsAvail,3*NBUFS/4
jle EchoLoop ; prevent buffer starving
call HardwareTicks
call DblShr10
mov dx,ax
sub ax,EchoNext ; time to send next echo pkt?
js EchoLoop0
add dx,EchoInterval
mov EchoNext,dx ; next send time
add EchoTx32+2,1 ; increment send counters
adc EchoTx32,0
mov EchoFudge,1
mov cx,EchoSize ; compute packet size
cmp MsgEchoSweep,'<'
jne EchoFillFixed
inc cx
cmp cx,EchoMaxSize
jbe EchoFillSize
mov cx,28-IPHDRLEN-ICMPHDRLEN
EchoFillSize:
mov EchoSize,cx
EchoFillFixed:
add cx,ICMPHDRLEN ; IP data length
mov ax,cx
add ax,IPHDRLEN+14+8+4+12 ; preamble, crc, intergap ...
cli
add EchoLoad+2,ax
adc EchoLoad,0
sti
mov di,cx
shl di,1
inc word ptr EchoSizeVec[di]
call HardwareTicks ; put timestamp
mov di,[bx].dPtrUdp
mov [di].uIcmpData,ax
mov [di].uIcmpData+2,dx
call SendIcmpPkt ; send echo pkt
jnz EchoErr ; any errors?
jmp EchoLoop
EchoErr:
xor ch,ch
cmp cl,SERRTABLEN
jb EchoErrExist
mov cl,SERRTABLEN
EchoErrExist:
mov si,cx
mov dx,MsgSerrTbl[si]
mov ah,9
int 21h ; display send error
EchoEnd:
call BufRelease ; release send buffer
mov EchoFudge,0
or ArgFlags,TERM_WAIT
ret
EchoAwhile endp
if DEBUG
TstBufLinks proc near
ja TstErrEI
mov si,di
inc cx
TstLinkLoop:
mov di,[di].dNext
mov si,[si].dPrev
loop TstLinkLoop
cmp si,di
jne TstErrEI
ret
TstBufLinks endp
TstErrEI:
PopfEI
TstErr:
push bx
mov bx,'>-'
push bx
push bx
call terminate
endif ; DEBUG
;************************************************************************
;* EchoDisplay
;************************************************************************
EchoDisplay proc near
if DEBUG
push bx
mov al,'s'-'0'
cmp word ptr phd_dioa,0 ; stack overflowed?
jne TstErr
mov al,'t'-'0'
cmp word ptr StackLow,0 ; stack overflowed?
jne TstErr
mov al,'i'-'0'
test GenFlags,DBGINTERR ; any interrupt debug errs?
jnz TstErr
mov cx,NBUFS ; any buffers damaged?
mov bx,offset BufStart
mov al,'u'-'0'
BufTestLoop:
cmp [bx].dHomeList,offset FreeBufs
jne TstErr
add bx,BUFSIZE
loop BufTestLoop
PushfDI
mov di,offset FreeBufs
mov cx,[di].lBufsAvail
cmp cx,NBUFS
call TstBufLinks
cmp di,offset FreeBufs
jne TstErrEI
PopfEI
mov cx,NBUFSMALL
mov al,'v'-'0'
TstSmlLoop:
cmp [bx].dHomeList,offset FreeSmal
jne TstErr
add bx,BUFSIZESML
loop TstSmlLoop
PushfDI
mov di,offset FreeSmal
mov cx,[di].lBufsAvail
cmp cx,NBUFSMALL
call TstBufLinks
cmp di,offset FreeSmal
jne TstErrEI
PopfEI
pop bx
endif ; DEBUG
cmp EchoTarget,0 ; are we pinging?
je EchoDispRet
call CurrentTicks
shr cx,1
shr cx,1
mov ax,EchoLastDispl
shr ax,1
shr ax,1
cmp ax,cx ; time to update display?
jne EchoDispNow
EchoDispRet:
ret
EchoDispNow:
push bx
cli
mov dx,EchoAvgSum
mov ax,EchoAvgSum+2
mov cx,EchoRx32
mov bx,EchoRx32+2
sti
call AdjTo16Bits
or bx,bx ; avoid div by zero
jz EchoSkipAvg
div bx
mov EchoAvg,ax ; average delay
EchoSkipAvg:
mov dx,EchoTx32 ; compute difference tx - rx
mov ax,EchoTx32+2
sub ax,EchoFudge ; subtract one if just
sbb dx,0 ; sent a pkt
push ax
push dx
cli
sub ax,EchoRx32+2
sbb dx,EchoRx32
sti
jns EchoDifPos ; use abs(tx-rx)
not ax
not dx
add ax,1
adc dx,0
EchoDifPos:
mov Echodif,dx
mov Echodif+2,ax
mov cl,2 ; compute packet loss
call DblShl ; multiply by 100
mov si,dx
mov bx,ax
mov cl,3
call DblShl
add bx,ax
adc si,dx
shl ax,1
rcl dx,1
add ax,bx
adc dx,si
pop cx
pop bx
call AdjTo16Bits
or bx,bx ; avoid div by zero
jz EchoSkipLoss
div bx
mov EchoLoss,ax
mov ax,dx ; fractional loss
mul k10000
div bx
mov EchoLoss+2,ax
EchoSkipLoss:
push cs ; edit echo values
pop es
mov di,offset MsgEcho-1
mov si,offset EchoTx32
mov PutNumFiller,' '
mov PutMinDigits,9
mov cx,3
call PutBigNums ; tx and rx and diff
mov PutMinDigits,6
inc di
mov cx,5
EchoDispLoop:
push cx
mov cl,1
call PutNums ; delays and loss
pop cx
loop EchoDispLoop
mov PutNumFiller,'0'
inc di
mov cl,1
call PutNumsD4 ; .0000%
cli
mov ax,EchoLoad+2
mov dx,EchoLoad
mov EchoLoad+2,0
mov EchoLoad,0
sti
div k27 ; assumes clr every 2nd tick
add di,4
mov PutNumFiller,' '
call PutNum ; load kb/s
call HardwareTicks ; compute elapsed time
mov ax,dx
mov dx,si
cmp dx,EchoLastHi
jae EchoLastGrows
mov bx,EchoLastDispl
mov cx,EchoLastHi
sub EchoStart+2,bx
sbb EchoStart,cx
EchoLastGrows:
mov EchoLastDispl,ax
mov EchoLastHi,dx
sub ax,EchoStart+2
sbb dx,EchoStart
mov cl,4 ; divide # of ticks by 18.2
call DblShr
mov EchoElapsed+2,ax
mov EchoElapsed,dx
mov cl,3
call DblShr
sub EchoElapsed+2,ax
sbb EchoElapsed,dx
mov cl,5
call DblShr
add ax,EchoElapsed+2
adc dx,EchoElapsed
mov PutNumFiller,' '
mov PutMinDigits,8
call PutBigNum ; elapsed time
if DEBUG
mov dx,280h+10h ; assume WD card at IO 280h
xor ax,ax
xor cx,cx
cli
out dx,al ; set page 0
call IoDelay
add dx,0dh
in al,dx ; readandclear frame err ctr
add cx,ax
inc dx
in al,dx ; readnadclear bad CRC ctr
add cx,ax
inc dx
in al,dx ; readandclear lost frames ctr
sti
add cx,ax
add EchoDrop,cx ; add out of bufs ctr
mov di,offset MsgEcho+18 ; place before diff
mov ax,EchoDrop
mov PutMinDigits,1
call PutNum ; show dropped packets
endif ; DEBUG
mov dx,offset MsgEcho ; display echo values
mov ah,9
int 21h
pop bx
ret
EchoDisplay endp
;************************************************************************
;* AdjTo16Bits
;************************************************************************
AdjTo16Bits proc near
AdjTest:
or cx,cx ; fits in 16 bits?
jnz Adjust
or dx,dx
jnz Adjust
ret
Adjust:
shr dx,1 ; shift 32 bits right
rcr ax,1
shr cx,1
rcr bx,1
jmp short AdjTest
AdjTo16Bits endp
;************************************************************************
;* DblShr
;************************************************************************
DblShr10 proc near
mov cl,10
DblShr:
xor ch,ch
DblShrNext:
shr dx,1 ; shift 32 bits right
rcr ax,1
loop DblShrNext
ret
DblShr10 endp
;************************************************************************
;* DblShl
;************************************************************************
DblShl proc near
xor ch,ch
DblShlNext:
shl ax,1 ; shift 32 bits left
rcl dx,1
loop DblShlNext
ret
DblShl endp
;************************************************************************
;* EchoCalc
;************************************************************************
even
kTimerScale dw TimerResolution
EchoCalc proc near
add EchoRx32+2,1 ; increment receive counters
adc EchoRx32,0
mov EchoFudge,0
mov ax,[bx].dPktLen ; IP data length
mov di,ax
add ax,IPHDRLEN+14+8+4+12 ; preamble, crc, intergap
add EchoLoad+2,ax
adc EchoLoad,0
shl di,1
dec word ptr EchoSizeVec[di]
call HardwareTicks ; compute delay
mov di,[bx].dPtrUdp
sub ax,[di].uIcmpData
sbb dx,[di].uIcmpData+2
js EchoCalcRet
div kTimerScale
mov EchoThis,ax ; delay for this packet
add EchoAvgSum+2,ax
adc EchoAvgSum,0
cmp ax,EchoMin
jb EchoSetMin
EchoChkMax:
cmp ax,EchoMax
ja EchoSetMax
EchoCalcRet:
ret
EchoSetMin:
mov EchoMin,ax ; minimum delay
jmp short EchoChkMax
EchoSetMax:
mov EchoMax,ax ; maximum delay
ret
EchoCalc endp
;************************************************************************
;* HardwareTicks (48 bit time to si:dx:ax in 838 ns units)
;************************************************************************
TimerResolution equ 1193 ; hw ticks per millisecond
InitTimer proc near
test ArgFlags,TIM_NOHIRES
jnz InitTimRet
mov dx,043h ; select timer control port
mov al,034h
out dx,al ; mode 2: Rate generator
call IoDelay ; (counts down by 1 to zero)
xor ax,ax
mov dx,040h ; select timer 0
out dx,al ; set divide by 2**16
call IoDelay
out dx,al ; the generator is now started
InitTimRet:
ret
InitTimer endp
RestoreTimer proc near
test ArgFlags,TIM_NOHIRES
jnz ResTimRet
mov dx,043h ; select timer control port
mov al,036h
out dx,al ; mode 3: Square wave generator
call IoDelay ; (counts down by 2 to zero,
xor ax,ax ; twice)
mov dx,040h ; select timer 0
out dx,al ; set divide by 2**16
call IoDelay
out dx,al
ResTimRet:
ret
RestoreTimer endp
IoDelay proc near
push ax
;*test in al,061h
pop ax
ret
IoDelay endp
HardwareTicks proc near
push es
PushfDI
test ArgFlags,TIM_NOHIRES
jnz HwTicksNoHi
mov dx,020h ;/* Address PIC ocw3 */
mov al,00Ah ;/* Ask to read irr */
out dx,al
xor al,al ;/* Latch timer 0 */
out 043h,al
in al,040h ;/* Counter --> ax*/
mov ah,al ;/* LSB in AH */
in al,040h ;/* MSB in AL */
xchg al,ah
not ax ;/* Need ascending counter */
push ax ; Save hardware counter value
in al,dx ;/* Read irr */
push ax ; Save irr
in al,021h ;/* Read PIC imr */
push ax ; Save imr
mov al,00FFh ;/* Mask all interrupts */
out 021h,al
mov ax,040h ;/* read low word of time */
mov es,ax ;/* from BIOS data area */
mov dx,es:[06Ch]
mov si,es:[06Ch+2] ; get high word too
pop ax ; Restore imr
out 021h,al
pop ax ; Restore irr
test al,001h ;/* Counter hit 0? */
pop ax ; Restore counter value
jnz HwTicksMore ;/* Jump if yes */
popfEI
pop es
ret
HwTicksMore:
cmp ax,0FFh ;/* Counter > 0x0FF? */
ja HwTicksDone ;/* Done if so */
inc dx ;/* Else count int req. */
HwTicksDone:
popfEI
pop es
ret
HwTicksNoHi:
mov ax,040h ;/* read low word of time */
mov es,ax ;/* from BIOS data area */
mov dx,es:[06Ch]
mov si,es:[06Ch+2]
xor ax,ax
popfEI
pop es
ret
HardwareTicks endp
;========================================================================
; endinclude